
local Folks = CreateFrame("Frame", "StatBlock_Folks")
local L_FRIENDS = _G["FRIENDS"]
local L_REALID = _G["BATTLENET_FRIEND"]
Folks.friends = LibStub("LibDataBroker-1.1"):NewDataObject("Folks_Friends", {type = "data source", text = "0 "..L_FRIENDS, value = 0, suffix = L_FRIENDS})

local L_TOOLTIP_F = "\n|cffeda55fClick|r to open the friends panel"
local L_TOOLTIP_G = "\n|cffeda55fClick|r to open the guild panel"

do
	local L = GetLocale()
	if L == "zhTW" then
		L_TOOLTIP_F = "\n|cffeda55f點擊|r 開啟好友名單"
		L_TOOLTIP_G = "\n|cffeda55f點擊|r 開啟公會名單"
	elseif L == "zhCN" then
		L_TOOLTIP_F = "\n|cffeda55f点击|r 开启好友名单"
		L_TOOLTIP_G = "\n|cffeda55f点击|r 开启公会名单"
	elseif L == "esES" or L == "esMX" then
		L_TOOLTIP_F = "\n|cffeda55fClic|r para mostrar el panel de amigos"
		L_TOOLTIP_G = "\n|cffeda55fClic|r para mostrar el panel de hermandad"
	elseif L == "deDE" then
		L_TOOLTIP_F = "\n |cffeda55fKlick|r, um das Kontaktfenster anzuzeigen "
		L_TOOLTIP_G = "\n|cffeda55fKlick|r, um das Gildenfenster anzuzeigen"
	end
end

local format = string.format
Folks:RegisterEvent("PLAYER_LOGIN")
Folks:SetScript("OnEvent", function(self, event) self[event](self) end)

function Folks:PLAYER_LOGIN()
	if IsInGuild() then GuildRoster() end
	ShowFriends()
end
-- System message when a friend or guild member is added/removed
Folks:RegisterEvent("CHAT_MSG_SYSTEM")
Folks.CHAT_MSG_SYSTEM = Folks.PLAYER_LOGIN

local function GetTipAnchor(frame)
	local x,y = frame:GetCenter()
	if not x or not y then return "TOPLEFT", "BOTTOMLEFT" end
	local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
	local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
	return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
end

local previousFrame

----------------------------
--        Friends         --
----------------------------
Folks:RegisterEvent("FRIENDLIST_UPDATE")

function Folks:FRIENDLIST_UPDATE()
	local bnTotal, bnCount = BNGetNumFriends()
	local fTotal, fCount = GetNumFriends()

	local total = bnCount+fCount
	self.friends.text = format("%d %s", total, L_FRIENDS)
	self.friends.value = total

	if GameTooltip:IsShown() and GameTooltipTextLeft1:GetText() == L_FRIENDS then
		self.friends.OnEnter(nil, "update")
	end
end

local function RGB2Hex(c)
	return format("%02x%02x%02x", c.r*255, c.g*255, c.b*255)
end

local function Friend2Color(class)
	local result
	for k,v in pairs(_G["LOCALIZED_CLASS_NAMES_FEMALE"]) do
		if v == class then
			result = k
		end
	end
	if not result then
		for k,v in pairs(_G["LOCALIZED_CLASS_NAMES_MALE"]) do
			if v == class then
				result = k
			end
		end
	end
	local c = _G["CUSTOM_CLASS_COLORS"] and _G["CUSTOM_CLASS_COLORS"][result] or _G["RAID_CLASS_COLORS"][result]
	return RGB2Hex(c)
end

local GetFriendInfo = GetFriendInfo
local BNGetFriendInfo = BNGetFriendInfo
function Folks.friends.OnEnter(frame, update)
	if frame then previousFrame = frame end

	GameTooltip:SetOwner(frame or previousFrame, "ANCHOR_NONE")
	GameTooltip:SetPoint(GetTipAnchor(frame or previousFrame))

	if update ~= "update" then
		GameTooltip:AddDoubleLine(L_FRIENDS, " ")
		GameTooltip:Show()
		ShowFriends()
		return
	end

	local bnTotal, bnCount = BNGetNumFriends()
	local fTotal, fCount = GetNumFriends()

	if bnTotal and bnTotal > 0 then
		GameTooltip:AddDoubleLine(L_REALID, format("[%d/%d]", bnCount, bnTotal), 0, 1, 1, 1, 1, 0.5)

		for i=1, bnCount do
			local _, name, _, _, _, _, _, isOnline, _, isAfk, isDnd, _, note = BNGetFriendInfo(i)
			if isOnline then
				local toon = BNGetNumFriendToons(i)
				for j = 1, toon do
					local _, toonName, client, realmName, _, _, _, class, _, zoneName, level, gametext = BNGetFriendToonInfo(i, j)
					local status = ""
					if note and note ~= "" then
						note = " [|cffffffff"..note.."|r]"
					else
						note = ""
					end
					if isAfk then
						status = "<"..DEFAULT_AFK_MESSAGE..">"
					elseif isDnd then
						status = "<"..DEFAULT_DND_MESSAGE..">"
					end
					if client == "WoW" then
						local difficultyColor = RGB2Hex(GetQuestDifficultyColor(tonumber(level) or 1))
						local classColor = Friend2Color(class)
						local groupIndicator = ""
						local zoneColor = " |cffffffff"

						zoneName = zoneName or _G["UNKNOWN"]

						if realmName == GetRealmName() then
							if UnitInParty(toonName) or UnitInRaid(toonName) then
								groupIndicator = "|cff0fff0f+|r"
							end
							if zoneName and (zoneName == GetRealZoneText() or zoneName == GetMapNameByID(GetCurrentMapAreaID())) then
								zoneColor = " |cff0fff0f"
							else
								zoneColor = " |cffffffff"
							end
						else
							zoneColor = " |cff7f7f7f"
						end

						GameTooltip:AddDoubleLine(
							format("%s%s: |cff%s%d|r |cff%s%s|r%s", groupIndicator, name, difficultyColor, level, classColor, toonName, note),
							status..zoneColor..zoneName.."|r"
						)
					else
						GameTooltip:AddDoubleLine(
							name..note, status.."|cffffffff"..client.."("..(gametext or "")..")".."|r"
						)
					end
				end
			end
		end
		if fTotal > 0 then
			GameTooltip:AddDoubleLine(" ", " ")
		end
	end

	if fTotal > 0 then
		GameTooltip:AddDoubleLine(L_FRIENDS, format("[%d/%d]", fCount, fTotal), 0, 1, 1, 1, 1, 0.5)
		for i = 1, fCount do
			local name, level, class, zone, _, status, note = GetFriendInfo(i)
			local difficultyColor = RGB2Hex(GetQuestDifficultyColor(level))
			local classColor = Friend2Color(class)
			local groupIndicator = ""
			local zoneColor = " |cffffffff"

			if UnitInParty(name) or UnitInRaid(name) then
				groupIndicator = "|cff0fff0f+|r"
			end

			note = note or ""
			zone = zone or _G["UNKNOWN"]

			if note ~= "" then
				note = " [|cffffffff"..note.."|r]"
			end

			if zone and (zone == GetRealZoneText() or zone == GetMapNameByID(GetCurrentMapAreaID())) then
				zoneColor = " |cff0fff0f"
			else
				zoneColor = " |cffffffff"
			end

			GameTooltip:AddDoubleLine(
				format("%s|cff%s%d|r |cff%s%s|r%s", groupIndicator, difficultyColor, level, classColor, name, note),
				status..zoneColor..zone.."|r"
			)
		end
	end

	GameTooltip:AddLine(L_TOOLTIP_F)
	GameTooltip:Show()
end

function Folks.friends.OnLeave()
	GameTooltip:Hide()
end

function Folks.friends.OnClick()
	ToggleFriendsFrame(1)
end

----------------------------
--         Guild          --
----------------------------

local L_GUILD = _G["GUILD"]
Folks.guild = LibStub("LibDataBroker-1.1"):NewDataObject("Folks_Guild", {type = "data source", text = "0 "..L_GUILD, value = 0, suffix = L_GUILD})

Folks:RegisterEvent("PLAYER_GUILD_UPDATE")
Folks:RegisterEvent("GUILD_ROSTER_UPDATE")

function Folks:GUILD_ROSTER_UPDATE()
	if not IsInGuild() then return end

	local _, online = GetNumGuildMembers()
	self.guild.text = format("%d %s", online, L_GUILD)
	self.guild.value = online

	if GameTooltip:IsShown() and GameTooltipTextLeft1:GetText() == L_GUILD then
		self.guild.OnEnter() -- Open on the previous frame
	end
end
Folks.PLAYER_GUILD_UPDATE = Folks.GUILD_ROSTER_UPDATE

do
	local function Guild2Color(class)
		local c = _G["CUSTOM_CLASS_COLORS"] and _G["CUSTOM_CLASS_COLORS"][class] or _G["RAID_CLASS_COLORS"][class]
		return RGB2Hex(c)
	end

	local GetGuildRosterInfo, Ambiguate = GetGuildRosterInfo, Ambiguate
	function Folks.guild.OnEnter(frame)
		if not IsInGuild() then return end
		if frame then previousFrame = frame end

		GuildRoster()
		GameTooltip:SetOwner(frame or previousFrame, "ANCHOR_NONE")
		GameTooltip:SetPoint(GetTipAnchor(frame or previousFrame))
		local total, online = GetNumGuildMembers()
		GameTooltip:AddDoubleLine(L_GUILD, format("[%d/%d]", online, total), 0, 1, 1, 1, 1, 0.5)

		GameTooltip:AddLine(GetGuildRosterMOTD().."\n", 1, 1, 1, true)

		for i = 1, GetGuildRosterShowOffline() and total or online do
			local name, rank, _, level, _, zone, note, officernote, online, status, trueClass = GetGuildRosterInfo(i)
			if online then
				name = Ambiguate(name, "guild")

				local difficultyColor = RGB2Hex(GetQuestDifficultyColor(level))
				local guildRankNoteText = " [|cffffffff"..rank.."|r]"
				local classColor = Guild2Color(trueClass)
				local groupIndicator = ""
				local zoneColor = " |cffffffff"

				if UnitInParty(name) or UnitInRaid(name) then
					groupIndicator = "|cff0fff0f+|r"
				end

				if note ~= "" and not CanViewOfficerNote() then
					guildRankNoteText = guildRankNoteText.."[|cffffffff"..note.."|r]"
				end

				if CanViewOfficerNote() and officernote ~= "" then
					guildRankNoteText = guildRankNoteText.."[|cffffffff"..officernote.."|r]"
				end

				if zone and (zone == GetRealZoneText() or zone == GetMapNameByID(GetCurrentMapAreaID())) then
					zoneColor = " |cff0fff0f"
				else
					zoneColor = " |cffffffff"
				end

				if status == 0 then
					status = ""
				elseif status == 1 then
					status = "<"..DEFAULT_AFK_MESSAGE..">"
				elseif status == 2 then
					status = "<"..DEFAULT_DND_MESSAGE..">"
				end
				GameTooltip:AddDoubleLine(
					format("%s|cff%s%d|r |cff%s%s|r%s", groupIndicator, difficultyColor, level, classColor, name, guildRankNoteText),
					status..zoneColor..(zone or _G["UNKNOWN"]).."|r"
				)
			end
		end
		GameTooltip:AddLine(L_TOOLTIP_G)
		GameTooltip:Show()
	end
end

function Folks.guild.OnLeave()
	GameTooltip:Hide()
end

function Folks.guild.OnClick()
	ToggleGuildFrame()
end

